# Code to test parsing of XML river data
# Parker MacCready 1/17/2014

import urllib2
import xml.etree.ElementTree as ET
import pandas as pd
from pandas import Series, DataFrame
import matplotlib.pyplot as plt

plt.close()
doLive = True

def fix_units(qt, flow_units):
    # fix units
    if flow_units == 'kcfs':
        qt = qt*28.3168466
    elif flow_units == 'cubic feet per second' or flow_units == 'ft3/s':
        qt = qt*0.0283168466
    return qt

if True:
    
    # AHPS
    if doLive:
        url_str = 'http://water.weather.gov/ahps2/hydrograph_to_xml.php?gage=mvew1&output=xml'
        file = urllib2.urlopen(url_str) # ** need error handling
        tree = ET.parse(file)
    else:
        tree = ET.parse('Skagit_test_AHPS_hydrograph_to_xml.php.xml')
    
    root = tree.getroot()

    """
    Here is a data line inside the <forecast> or <observed> tag:

    <datum>
        <valid timezone="UTC">2014-01-17T18:00:00-00:00</valid>
        <primary name="Stage" units="ft">7.99</primary>
        <secondary name="Flow" units="kcfs">4.88</secondary>
        <pedts>HGIFZ</pedts>
    </datum>
    """

    Q = []
    T = []
    flag = True
    for e0 in root.findall(".//"):
        if e0.tag == 'observed' or e0.tag == 'forecast':
            for e in e0:
                if e.tag == 'datum':
                    for ee in e:
                        if ee.get('name') == 'Flow':
                            Q.append(float(ee.text))
                            if flag:
                                flow_units = ee.get('units')
                                flag = False
                        if ee.get('timezone') == 'UTC':
                            T.append(pd.to_datetime(ee.text))
                
    qt = Series(Q, index=T)
    qt.sort_index() # the observed data is listed backwards in time, so sort
    qt = fix_units(qt, flow_units)
    
    plt.plot(qt.index,qt.values,'+b', label='AHPS', markersize=10)
    
if True:
    
    # NWRFC
    if doLive:
        url_str = 'http://www.nwrfc.noaa.gov/xml/xml.cgi?id=MVEW1&pe=HG&dtype=b&numdays=10'
        file = urllib2.urlopen(url_str) # ** need error handling
        tree = ET.parse(file)
    else:
        tree = ET.parse('Sakgit_test_NWRFC_xml.cgi.xml')
    
    root = tree.getroot()

    """
    Here is a data line inside the <observedData> tag:

    <observedValue petype="HG" durCode="0" tsCode="RZ" extremumCode="Z">
        <dataDateTime>2014-01-07T23:30:00Z</dataDateTime>
        <stage units="feet">14.35</stage>
        <discharge units="cubic feet per second">12650</discharge>
    </observedValue>

    and this is inside the <forecastData> tag:

    <forecastValue petype="HG" durCode="0" tsCode="FZ" extremumCode="Z">
        <creationDateTime>2014-01-17T17:01:00Z</creationDateTime>
        <dataDateTime>2014-01-18T00:00:00Z</dataDateTime>
        <stage units="feet">16.55</stage>
        <discharge units="cubic feet per second">18767</discharge>
    </forecastValue>
    """

    Q = []
    T = []
    flow_units = ''
    flag = True
    # NOTE: you find this tag by looking at any instance of e0.tag
    aa = '{http://www.nwrfc.noaa.gov/xml/schemas/2004/03/hydromet_data}'
    for e0 in root.findall(".//"):
        if e0.tag == aa+'observedData' or e0.tag == aa+'forecastData':
            for e in e0:
                if e.tag == aa+'observedValue' or e.tag == aa+'forecastValue':
                    for ee in e:
                        if ee.tag == aa+'discharge':
                            Q.append(float(ee.text))
                            if flag:
                                flow_units = ee.get('units')
                                flag = False
                        if ee.tag == aa+'dataDateTime':
                            T.append(pd.to_datetime(ee.text))
                
    qt = Series(Q, index=T)
    qt = fix_units(qt, flow_units)
    plt.plot(qt.index,qt.values,'.r', label='NWRFC', markersize=2)
    
if True:
    
    # USGS
    if doLive:
        url_str = ('http://waterservices.usgs.gov/nwis/iv/' +
        '?format=waterml,1.1&sites=12200500&period=P6D&parameterCd=00060')
        file = urllib2.urlopen(url_str) # ** need error handling
        tree = ET.parse(file)
    else:
        tree = ET.parse('Skagit_test_USGS_waterservices.usgs.gov.xml')
    
    root = tree.getroot()

    """
    Here is a data line inside the <ns1:values> tag:

    <ns1:value qualifiers="P" dateTime="2014-01-11T15:30:00.000-08:00">31700</ns1:value>   
    """

    Q = []
    T = []
    flow_units = ''
    flag = True
    aa = '{http://www.cuahsi.org/waterML/1.1/}'
    for e0 in root.findall(".//"):
        if e0.tag == aa+'value':
            Q.append(float(e0.text))
            T.append(pd.to_datetime(e0.get('dateTime')))
        if e0.tag == aa+'unitCode' and flag:
            flow_units = e0.text
            flag = False
                                       
    qt = Series(Q, index=T)    
    #qt.tz_convert('UTC') # USGS reports in local time
    qt = fix_units(qt, flow_units)
    plt.plot(qt.index,qt.values,'og', label='USGS', markersize=5)

plt.title('Sakgit flow')
plt.grid()
plt.xlabel('Time (UTC)')
plt.ylabel('Flow (m3/s)')
plt.legend(loc='best', fontsize='small')
plt.show()

                

